import { Body, Controller, Get, HttpStatus, Param, ParseIntPipe, Post, Put, Query, Req, Res, UploadedFile, UseInterceptors } from '@nestjs/common';
import { UserService } from './user.service';
import { UtilsService } from '@app/utils';
import { WechatService } from '../wechat/wechat.service';
import { createDecipheriv } from 'crypto'
import { FileInterceptor } from '@nestjs/platform-express';
import { UploadService } from 'apps/common/src/upload/upload.service';

@Controller('user')
export class UserController {
    constructor(
        private readonly service:UserService,
        private utils:UtilsService,
        private wechat:WechatService,
        private upload:UploadService,
    ) {}

    @Get('balance/list')
    async balanceList(@Req() { userId }) {
        const balances = await this.service.getUserBalance(userId)
        return this.utils.successRes(balances)
    }

    @Get('balance')
    async balance(@Req() { userId }) {
        const balance = await this.service.getUserAvailableBalance(userId)
        return this.utils.successRes(balance)
    }

    @Get('balance/logs')
    async page(@Query() query:Pagination, @Req() { userId }) {
        let rows = await this.service.balanceRecord(query, userId)
        return this.utils.successRes(rows)
    }

    //用户授权免密支付回调
    @Post('payscore/permissions/:client/:userId')
    async payscorePermissions(@Param('userId', ParseIntPipe) userId:number, @Param('client') client:string, @Body() data:any, @Res() res) {
        if(isNaN(userId) || userId < 1) return

        try {
            if(client == 'wx') {
                if(data.event_type == 'PAYSCORE.USER_OPEN_SERVICE' || data.event_type == 'PAYSCORE.USER_CLOSE_SERVICE') {
                    const r = await this.service.payscorePermissions(userId, data.resource, true)
                    console.log(r)
                    if(r) {
                       res.status(HttpStatus.OK).send();
                    }else {
                        res.status(HttpStatus.NOT_IMPLEMENTED).send({code : 'FAIL', message : "失败"});
                    }
                }     
                
            }else {
    
            }

            return
        } catch (error) {
            
        }
        
        res.status(HttpStatus.NOT_IMPLEMENTED).send({code : 'FAIL', message : "失败"});
    }

    //查询用户免密支付授权状态
    @Get('free/pay/status')
    async freePayStatus(@Req() { user, isWx, userId }) {
        if(isWx) {
            const r0 = await this.wechat.queryPayscorePermissions(user.openid)
            if(r0 == null) return this.utils.failRes('无法支付')
            if(r0.authorization_state == 'AVAILABLE') { //已经授权
                this.service.update({id : userId}, {payscore : 1})
                return this.utils.successRes({
                    status : true
                })
            }

            //未授权，获取授权码
            const r1 = await this.wechat.payscorePermissions(r0.authorization_code, userId)

            if(r1 != null && ('apply_permissions_token' in r1)) {
                return this.utils.successRes({
                    status : false,
                    code : r1.apply_permissions_token
                })
            }
        }


    }

    


    //手机号授权
    @Post('auth')
    async auth(@Body() body:{code:string,encryptedData:string,iv:string}, @Req() { userId, user, isWx }) {
        
        try {
            let r:any = {}
            if(isWx) {
                //解密用户信息
                var sessionKey = Buffer.from(user.session_key, 'base64')
                var encryptedData = Buffer.from(body.encryptedData, 'base64')
                var iv = Buffer.from(body.iv, 'base64')

                // 解密
                var decipher = createDecipheriv('aes-128-cbc', sessionKey, iv)
                // 设置自动 padding 为 true，删除填充补位
                decipher.setAutoPadding(true)
                var decoded = decipher.update(encryptedData, undefined, 'utf8')
                decoded += decipher.final('utf8')

                r = JSON.parse(decoded)
            }else {
                let msg = JSON.parse(body.encryptedData)
                let crypted = msg.response // 密文
                crypted = Buffer.from(crypted, 'base64').toString('binary');
                var key = Buffer.from('6o62bJBDUYwg5oN91xFL8w==', 'base64');
                const iv = Buffer.alloc(16, 0)
                const decipher = createDecipheriv('aes-128-cbc', key, iv);
                let decoded = decipher.update(crypted, 'binary', 'utf8');
                decoded += decipher.final('utf8');
                // 打印解密结果
            console.log(decoded);
            }
            //return

            if(r.phoneNumber != undefined) {
                const user = await this.service.findOne({phone : r.phoneNumber}, ['id'])
                if(user != null) {
                    return this.utils.failRes('该手机号已经被使用')
                }

                await this.service.update({id : userId}, {phone : r.phoneNumber})
            }
       
         } catch (err) {
           throw new Error('Illegal Buffer')
         }

        return this.utils.successRes()
       
         

        //const phone = await this.wechat.getuserphonenumber(body.code)
    }

    @Post('update/info')
    async update(@Body() body, @Req() { userId }) {
        this.service.update({id : userId}, body)
        return this.utils.successRes()
    }

    @Post('upload/info')
    @UseInterceptors(FileInterceptor('avatar'))
    async updateInfo(@UploadedFile() avatar: Express.Multer.File, @Body() body, @Req() { userId }) {
        const user = await this.service.findOne({id : userId}, ['avatar', 'nickname'])
        if(!user) return this.utils.failRes()
        const fileName = await this.upload.put(avatar, userId)
        const updateData:any = {
            avatar : fileName,
        }
        if(body.nickname != undefined && user.nickname != body.nickname) {
            updateData.nickname = body.nickname
        }

        const r = await this.service.update({id : userId}, updateData)
        if(r == 1) {
            if(user.avatar != '') {
                this.upload.delFile(user.avatar)
            }
            return this.utils.successRes({
                avatar : fileName
            })
        }else {
            return this.utils.failRes()
        }
        
    }
}

